import logging
from http.client import HTTPException
from typing import List

from fastapi.routing import APIRouter
from starlette.status import HTTP_404_NOT_FOUND
from tortoise import transactions
from tortoise.contrib.pydantic import pydantic_model_creator

from ModelPydantic import CustomerIn, KumquatIn
from models import Customer

customer = APIRouter()


@customer.get("/schema", tags=["Get Customer Schema"], summary="Well it's not readable...",
         description="Schema Test",
         response_description="Return the Customer Schema")
async def get_customer_schema():
    customerPydantic = pydantic_model_creator(Customer)
    return {'message': customerPydantic.model_json_schema()}


@customer.get("/all", tags=["Get All Customers"], summary="List All Customers",
              description="Fetches a list of all customer records.",
              response_description="A list of all customers is returned.")
async def get_all_customer():
    customers = await Customer.all()
    return {'message': 'OK', 'data': customers}, 200

@customer.post("/all", tags=["Bulk Create Customers"], summary="Bulk Create Customers",
              description="Receive a list of customer records.",
              response_description="Return success or failed code.")
async def bulk_create_customer(custsIn: List[CustomerIn]):
    custNonExits = []
    for custIn in custsIn:
        custFilter = {}
        if custIn.name != 'None':
            custFilter['name'] = custIn.name
        if custIn.address != 'None':
            custFilter['address'] = custIn.address
        if custIn.phoneNumber != 'None':
            custFilter['phoneNumber'] = custIn.phoneNumber
        custFilter['presenter'] = custIn.presenter
        cust = await Customer.filter(**custFilter).first()
        if not cust:
            for ele in custNonExits:
                if compare_customer(ele, Customer(**custFilter)):
                    print("Customer already in the list to append.")
                    continue
            custNonExits.append(Customer(**custFilter))
    if len(custNonExits):
        print("Customers exits, no need to insert.")
    async with transactions.in_transaction():  # make sure atomics
        await Customer.bulk_create(custNonExits)
    return {'message': 'OK',}, 201

def compare_customer(customerA:Customer, customerB:Customer):
    return customerA.name == customerB.name and customerA.address == customerB.address and \
        customerA.phoneNumber == customerB.phoneNumber and customerA.presenter == customerB.presenter

@customer.get("/<customer_id>", tags=["Get Single Customer"], summary="Find Customer by ID",
              description="Retrieves a single customer record based on the provided customer ID.",
              response_description="The matching customer record is returned.")
async def get_customer_id(customer_id):
    customerById = await Customer.filter(customer_id=customer_id)
    return {"message": 'OK', 'data': customerById}, 200

@customer.get("/", tags=["Search Customers"], summary="Search Customers by Criteria",
              description="Searches for customers based on specified name, address, presenter, and phone number.",
              response_description="A list of customers matching the criteria is returned.")
async def get_customer(name, address, presenter, phoneNumber):
    filters = {}
    if name != 'None':
        filters['name'] = name
    if address != 'None':
        filters['address'] = address
    if phoneNumber != 'None':
        filters['phoneNumber'] = phoneNumber
    if presenter != 'None':
        filters['presenter'] = presenter
    customerFound = await Customer.filter(**filters)
    return {"message": 'OK', 'data': customerFound}, 200


@customer.post("/")
async def add_customer(customerIn: CustomerIn):
    customerInsert = await Customer.create(name=customerIn.name, address=customerIn.address,
                              phoneNumber=customerIn.phoneNumber, presenter=customerIn.presenter)
    await customerInsert.save()
    return {"message": "OK"}, 201

@customer.delete("/")
async def del_customer(name, address, presenter, phoneNumber):
    filters = {}
    if name != 'None':
        filters['name'] = name
    if address != 'None':
        filters['address'] = address
    if phoneNumber != 'None':
        filters['phoneNumber'] = phoneNumber
    if presenter != 'None':
        filters['presenter'] = presenter
    customerFound = await Customer.filter(**filters).delete()
    if not customerFound:
        raise HTTP_404_NOT_FOUND(detail=f"Customer for {filters} not found.")

    return {"message": 'OK', 'data': customerFound}, 201

@customer.get("/presenter")
async def get_presenter():
    presenters = await Customer.filter().distinct().values('presenter')
    return {"message": 'OK', 'data': presenters}, 201